function TrProgress(tableRow, item, callbackFunc, options) {
  this._tableRow = tableRow;
  this._item = item;
  this._callbackFunc = callbackFunc;

  this._music = (options && options.music) ? options.music : null;
  this._precon = (options && options.precon) ? options.precon : null;
  this._photographer = (options && options.photographer) ? options.photographer : null;
  this._videographer = (options && options.videographer) ? options.videographer : null;
  this._makeup = (options && options.makeup) ? options.makeup : null;
  this._produce = (options && options.produce) ? options.produce : null;
  this._video = (options && options.video) ? options.video : null;
  this._p4x6 = (options && options.p4x6) ? options.p4x6 : null;
  this._pretouch = (options && options.pretouch) ? options.pretouch : null;
  this._pcommon = (options && options.pcommon) ? options.pcommon : null;
  
  this._host = (options && options.host) ? options.host : null;
  this._now = (options && options.now) ? options.now : null;
  this._registrar = (options && options.registrar) ? options.registrar : null;
  this._validate = (options && options.validate) ? options.validate : null;
  
  this._createElements();
};

TrProgress.prototype._createElements = function() {
  var unique, input, _self = this;
  
  DOMUtils.removeChildElements(this._tableRow);
  
  unique = MiscUtils.unique();
  new TrProgressGui(unique, this._tableRow, this._item, { music: this._music, precon: this._precon, photographer: this._photographer, videographer: this._videographer, makeup: this._makeup, produce: this._produce, video: this._video, p4x6: this._p4x6, pretouch: this._pretouch, pcommon: this._pcommon, registrar: this._registrar });
  
  for (var i = 0, il = this._item.orders.length; i < il; i++) {
    var order = this._item.orders[i];

    var func = function() { if (!_self._validate(_self._item)) {
                              _self._callbackFunc();
                            } else {
                              _self._retrieveCustomer.call(_self);
                            }
                          };
    
    if (this._music) {
      itd = document.getElementById('itd' + unique + i + '1');
      new EditStatus(itd, order.music, func, { host: this._host, order: order, now: this._now, registrar: this._registrar, key: '{{$smarty.const.MODEL_NAME_MUSIC|escape:javascript}}' });
    }
    
    if (this._precon) {
      itd = document.getElementById('itd' + unique + i + '2');
      new EditStatus(itd, order.precon, func, { host: this._host, order: order, now: this._now, registrar: this._registrar,  key: '{{$smarty.const.MODEL_NAME_PRECON|escape:javascript}}' });
    }
    
    for (var j = 0, jl = order.tasks.length; j < jl; j++) {
    
      var task = order.tasks[j];
      if (this._photographer) {
        for (var k = 0, kl = task.photographers.length; k < kl; k++) {
          var photographer = task.photographers[k];
          itd = document.getElementById('itd' + unique + i + j + k + '3');
          new EditStatus(itd, photographer.status, func, { host: this._host, order: order, now: this._now, registrar: this._registrar,  key: '{{$smarty.const.MODEL_NAME_USER_PHOTOGRAPHER|escape:javascript}}' });
        }
      }
      if (this._videographer) {
        for (var k = 0, kl = task.videographers.length; k < kl; k++) {
          var videographer = task.videographers[k];
          itd = document.getElementById('itd' + unique + i + j + k + '4');
          new EditStatus(itd, videographer.status, func, { host: this._host, order: order, now: this._now, registrar: this._registrar,  key: '{{$smarty.const.MODEL_NAME_USER_VIDEOGRAPHER|escape:javascript}}' });
        }
      }
      if (this._makeup) {
        for (var k = 0, kl = task.makeups.length; k < kl; k++) {
          var makeup = task.makeups[k];
          itd = document.getElementById('itd' + unique + i + j + k + '5');
          new EditStatus(itd, makeup.status, func, { host: this._host, order: order, now: this._now, registrar: this._registrar,  key: '{{$smarty.const.MODEL_NAME_USER_MAKEUP|escape:javascript}}' });
        }
      }
    }
    
    for (var m = 0, ml = order.produces.length; m < ml; m++) {
      var produce = order.produces[m];
      if (!this._produce) {
        if (produce.product.model == '{{$smarty.const.MODEL_NAME_PRODUCT_VIDEO|escape:javascript}}' && !this._video) {
          continue;
        } else if (produce.product.model == '{{$smarty.const.MODEL_NAME_PRODUCT_4X6|escape:javascript}}' && !this._p4x6) {
          continue;
        } else if (produce.product.model == '{{$smarty.const.MODEL_NAME_PRODUCT_RETOUCH|escape:javascript}}' && !this._pretouch) {
         continue;
        } else if (produce.product.model == '{{$smarty.const.MODEL_NAME_PRODUCT_COMMON|escape:javascript}}' && !this._pcommon) {
          continue;
        }
      }
      
      if (this._registrar.type == '{{$smarty.const.USER_TYPE_DESIGNER|escape:javascript}}' && this._registrar.id != produce.assignee.userId) {
        continue;
      }
      
      itd = document.getElementById('itd' + unique + i + m + '6');
      new EditStatus(itd, produce.status, func, { host: this._host, order: order, now: this._now, registrar: this._registrar,  key: produce.product.model });
    }
  }
};

TrProgress.prototype._retrieveCustomer = function() {
  var _self = this;
  new RequestUtils()._read('customer', null, 'd.oid = ' + this._item.id, null, null, null, null, function(result, params) { _self._item = (result.data.length == 1) ? result.data[0] : null;
                                                                                                                            _self._createElements.call(_self);
                                                                                                                          }, { php: ((this._host) ? this._host + '/jsonread.php' : null) });
};